Empresas
Empregos
  • Sobre nós
  • Soluções
    • Publicação de vagas
      Publique sua vaga e receba candidatos qualificados em 48h.
    • Avaliações de candidatos
      Mais de 500 testes técnicos e psicológicos, mais anti-fraude.
    • Headhunting
      Busca executiva personalizada do início ao fim.
    • Folha de Pagamento + EOR
      Dispersão de folha e EOR em mais de 15 países da LATAM.
  • Preços
  • Empregos

0

152
Visualizações
SetInterval "Stacking" on top of each other

I'm working on this project which uses setInterval and I'm having a little trouble understanding how setInterval works. The problem I'm having is that the each time I call setInterval the function seems to stack on top of each other resulting in the object appearing multiple times rapidly. I'm not sure what I'm doing wrong in this case. Can someone please help me out thanks.

const [hit, setHit] = useState(0)
const [count, setCount] = useState(0)
var timer = null
var funcCalls = 0
const hitSound = new Audio("/hit.wav")
useEffect(()=>{
    timer = setInterval(moveSquare, 2000)
},[])
function handleHit(){
    hitSound.play()
    setHit(hit+1)
    resetSquare()
}
function resetSquare(){
    clearInterval(timer)
    moveSquare()
    timer = setInterval(moveSquare, 2000)
}
function moveSquare(){
    const gameContainer = document.getElementById("game-container")
    const height = gameContainer.offsetHeight
    const width = gameContainer.offsetWidth
    const square = document.getElementById("square")
    square.style.top = (Math.random() * (height - 100)) + "px";
    square.style.left = (Math.random() * (width - 100)) + "px";
}
return (
    <>
    <section className='game-section'>
        <div className='counter'>
            {hit}
            {count}
        </div>
        <div className='game-container' id = "game-container">
            <div className="square" id = "square" onClick={handleHit}></div>
        </div>
    </section>
    </>
)
about 4 years ago · Juan Pablo Isaza
2 Respostas
Responde à pergunta

0

It's because the timer value isn't saved across renders so you can't cancel it.

var timer = null // <-- no
const [timer, setTimer] = useState(null) // <-- yes
...
// later in useEffect() and resetSquare()
// save the timer using setTimer(timer)
about 4 years ago · Juan Pablo Isaza Relatório

0

Reason for that is elsewhere: your component (and/or and of its parent) is recreated. There are just few reasons in general but it's hard to point a specific line of code without debugging:

  • Either conditional rendering (e.g. showing spinner during request and after render element with children again)
  • Or different key prop is provided
  • Or by mistake you put component declaration(function or class or wrap into HOC) inside of other component's render code and every time parent is rerendered, component's declaration becomes referentially different

Another root cause: your useEffect does not have cleanup. While it should. And even without first reason, you would not have multiple concurrent timers but you still would have timer that would not stop when you're navigating away.

useEffect(()=>{
    timer = setInterval(moveSquare, 2000)
    return () => clearInterval(timer);
},[])

More on cleanup in official docs: https://reactjs.org/docs/hooks-effect.html#effects-with-cleanup

about 4 years ago · Juan Pablo Isaza Relatório
Responde à pergunta
Encontrar trabalhos remotos

Descubra a nova forma de encontrar um emprego!

melhores empregos
Principais categorias de trabalho
Empresas
Postar vaga Preços Comercial
Jurídico
Termos e Condições Política de privacidade
© 2026 PeakU Inc. All Rights Reserved.
Andres GPT
Recomende algumas ofertas para mim
Preciso de ajuda